package com.tjetc.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tjetc.constant.RedisConstant;
import com.tjetc.entity.po.User;
import com.tjetc.entity.request.LoginRequest;
import com.tjetc.mapper.UserMapper;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import static com.tjetc.constant.RedisConstant.*;


/**
 * @author gaoyongxiang
 * @version v1.0
 * @since 2025-10-20
 */
@RestController
@RequestMapping("/user/")
@SuppressWarnings("all")
public class UserController {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();


    @Autowired
    private UserMapper userMapper;

    @PostMapping("/code")
    public String code(@RequestParam("phone") String phone, HttpSession session){
        // 业务直接在controller写了
        // 1. 校验手机号
        // 2. 生成验证码
        // 100 - 1000 0 - 1.0 (int) 0 - 900.00000  100 -  1000

        String code = String.valueOf((int)((Math.random() * 900)) + 100);
        // 3. 将验证码放入session
        // session.setAttribute("code", code); set k1 v1
        // key 要自己维护 我们一般根据业务来定义key的值
        redisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, Duration.ofMinutes(LOGIN_CODE_TTL));
        // 4. 返回验证码
        return code;
    }


    @PostMapping("login")
//    public User login(@RequestBody LoginRequest loginRequest, HttpSession session){
    public String login(@RequestBody LoginRequest loginRequest, HttpSession session){
        // 思路分析：
        /*
            1. 校验手机号 【空 格式校验】
            2. 从session中获取code
            3. 校验code
            4. 使用手机号查询用户信息
            5. 判断用户是否存在
            6. 如果不存在 直接注册用户
            7. 将用户信息保存到session中
         */
//        String code = session.getAttribute("code").toString();
        String code = redisTemplate.opsForValue().get(LOGIN_CODE_KEY + loginRequest.getPhone()).toString();
        if (!Objects.equals(loginRequest.getCode(), code)) {
            return null;
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", loginRequest.getPhone());
        User user = userMapper.selectOne(queryWrapper);

        if (Objects.isNull(user)) {
            // 创建用户
            user = createUser(loginRequest.getPhone());
        }

        // session.setAttribute("user", user);
        /*
            正常业务 登录成功后返回的是token值 用户信息是前端登录成功后携带token值再次请求获取用户信息
         */
        String token = UUID.randomUUID().toString(true);
        String tokenKey = LOGIN_TOKEN + token;
        // 省略往redis中存入用户对象 提示可以使用beanutils进行拷贝 mapreduce
//        Map<String, String> userMap = new HashMap<>();
//        userMap.put("userId", String.valueOf(user.getUserId()));
        // BeanUtil: 对象转换工具 专门用于对象之间的类型转换
        Map<String, Object> userMap = BeanUtil.beanToMap(user);
        redisTemplate.opsForHash().putAll(tokenKey, userMap);
        // 我们要设置token的有效期
        redisTemplate.expire(tokenKey, Duration.ofMinutes(LOGIN_TOKEN_TTL));
        return token;
    }

    // 根据手机号 创建用户
    private User createUser(Integer phone) {
        User user = new User();
        user.setPhone(phone);
        userMapper.insert(user);
        return user;
    }


    @GetMapping("f1")
    public void f1() {
        System.out.println("f1");
    }


    @GetMapping("f2")
    public void f2() {
        System.out.println("f1");
    }


}
